﻿namespace FiftyOne
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Threading;

    internal abstract class Log
    {
        private Queue<string> _queue = new Queue<string>();
        private bool _running = false;
        protected static object _syncQueue = new object();
        protected static object _syncWait = new object();

        protected Log()
        {
        }

        private bool IsQueueEmpty()
        {
            return (this._queue.Count == 0);
        }

        protected void Run(object stateInfo)
        {
            while (!this.IsQueueEmpty())
            {
                FileStream stream = null;
                try
                {
                    if (!string.IsNullOrEmpty(this.LogFile))
                    {
                        stream = File.Open(this.LogFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
                        StreamWriter writer = null;
                        try
                        {
                            writer = new StreamWriter(stream);
                            while (!this.IsQueueEmpty())
                            {
                                lock (_syncQueue)
                                {
                                    string str = this._queue.Peek();
                                    if (str != null)
                                    {
                                        writer.WriteLine(str);
                                        this._queue.Dequeue();
                                    }
                                }
                            }
                            writer.Flush();
                        }
                        catch
                        {
                            this._running = false;
                            return;
                        }
                        finally
                        {
                            if (writer != null)
                            {
                                writer.Close();
                                writer.Dispose();
                            }
                        }
                    }
                }
                catch
                {
                    this._running = false;
                    return;
                }
                finally
                {
                    if (stream != null)
                    {
                        stream.Close();
                        stream.Dispose();
                    }
                }
                Thread.Sleep(50);
            }
            this._running = false;
        }

        protected internal void Write(string message)
        {
            object obj2;
            if ((this._queue.Count > 100) && this._running)
            {
                lock ((obj2 = _syncWait))
                {
                    if ((this._queue.Count > 100) && this._running)
                    {
                        Thread.Sleep(10);
                    }
                }
            }
            lock ((obj2 = _syncQueue))
            {
                this._queue.Enqueue(message);
            }
            if (!this._running)
            {
                lock ((obj2 = _syncQueue))
                {
                    if (!this._running)
                    {
                        this._running = true;
                        ThreadPool.QueueUserWorkItem(new WaitCallback(this.Run));
                    }
                }
            }
        }

        protected abstract string LogFile { get; }
    }
}

